package gui.text;

import java.awt.Component;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JTextPane;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Element;
import javax.swing.text.StyleConstants;

public class FocusDownKeyListener implements KeyListener {
    
    private final JTextPane defaultEditor;
    
    /**
     * 
     */
    public FocusDownKeyListener(JTextPane editorToLeave)
    {
        if(editorToLeave == null) {
            throw new NullPointerException("Null in " + this.getClass().getName());
        }
        defaultEditor = editorToLeave;
    }
    
    /*
     * (non-Javadoc)
     * 
     * @see java.awt.event.KeyListener#keyTyped(java.awt.event.KeyEvent)
     */
    @Override
    public void keyTyped(KeyEvent e)
    {
        // Nothing to do.
    }
    
    /*
     * (non-Javadoc)
     * 
     * @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent)
     */
    @Override
    public void keyPressed(KeyEvent e)
    {
        if(e.getKeyCode() == KeyEvent.VK_LEFT) {
            int dot = defaultEditor.getCaret().getDot();
            try {
                if(dot > 0) {
                    if(defaultEditor.getText(dot - 1, 1).endsWith(" ")) {
                        switchToComponentAt(dot - 1);
                    }
                }
            }
            catch(BadLocationException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }
        else if(e.getKeyCode() == KeyEvent.VK_RIGHT) {
            int dot = defaultEditor.getCaret().getDot();
            try {
                if(defaultEditor.getText(dot, 1).endsWith(" ")) {
                    switchToComponentAt(dot);
                }
            }
            catch(BadLocationException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }
        else if(e.getKeyCode() == KeyEvent.VK_UP) {
            // TODO
        }
        else if(e.getKeyCode() == KeyEvent.VK_DOWN) {
            // TODO
        }
    }
    
    /**
     * Switches focus to a Component within the JTextPane at position dot, if it exists.
     * 
     * @param dot
     *            the position of the component.
     */
    private void switchToComponentAt(int dot)
    {
        Element elem = defaultEditor.getDocument().getDefaultRootElement();
        Component c = findComponent(elem, dot);
        if(c != null) {
            c.requestFocusInWindow();
        }
    }
    
    /*
     * (non-Javadoc)
     * 
     * @see java.awt.event.KeyListener#keyReleased(java.awt.event.KeyEvent)
     */
    @Override
    public void keyReleased(KeyEvent e)
    {
        // Nothing to do.
    }
    
    private Component findComponent(Element elem, int pos)
    {
        Component component = null;
        boolean outOfBounds = false;
        for(int i = 0; !outOfBounds && i < elem.getElementCount(); i++) {
            if(elem.getElement(i).getStartOffset() <= pos
                    && elem.getElement(i).getEndOffset() >= pos) {
                component = findComponent(elem.getElement(i), pos);
            }
            else if(elem.getElement(i).getStartOffset() > pos
                    || elem.getElement(i).getEndOffset() < pos) {
                outOfBounds = true;
            }
        }
        if(component == null) {
            AttributeSet attributes = elem.getAttributes();
            component = (Component) attributes.getAttribute(StyleConstants.ComponentAttribute);
        }
        return component;
    }
}
